#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Datetime: 2020/12/16 15:45
# @Author  : thinkive_cfy_ide_3
# @Site    : 
# @File    : bond_info.py
# @Software: PyCharm 

"""
债券信息相关函数
"""

from quant_researcher.quant.project_tool import time_tool
from quant_researcher.quant.project_tool.celebrity import get_lst_condition
from quant_researcher.quant.project_tool.db_operator import db_conn, my_mysql
from quant_researcher.quant.project_tool.logger.my_logger import LOG

EARLIEST_START_DATE = '19000101'
# 债券编码信息表
BOND_INFO_TABLE = 'bnd_bd_overview'
CONV_BOND_VALUATION = 'bnd_conv_valuation_month'


def get_bond_basic_info(bond_code, select=None):
    """
    获取债券基本信息

    :param str or list bond_code: 债券代码, 可以是单个债券（类型为str），或者多个债券（类型为列表）
    :param list select: 债券信息字段，可选如下：
                secinner_code:证券内部编码
                bond_uid   :债券唯一编码
                bond_code    :债券代码
                bond_name    :债券全称
                bond_sname   :债券简称
                is_pubcompany:发行主体是否是上市公司
                is_multientity:是否有多个发行主体
                is_cross:是否跨市场
                bond_form:债券形态
                bond_nature:债券类别
                info_pubdate:首次信息公布时间
                plan_issuance_scale:计划发行总额(元)
                actual_issuance_scale:实际发行总额(元)
                maturity_years:债券期限(年)
                maturity_days:债券期限(天)
                opspmaturity:含权券特殊期限
                par_value:初始债券面值(元)
                issue_price:初始发行价格(元)
                currency:币种
                cashpayment_mode:兑付方式
                caluinterest_mode:计息方式
                intpayment_mode:付息方式
                intpayment_freq:付息频率(次/年)
                apintPayment_mode:摊还期付息方式
                interest_formula:利息计算公式(赋值)
                coupon_Rate:初始票面年利率(%)
                frncaluint_beachmark:浮动利率计息基准
                beachmark_initialrate:初始基准利率(%)
                beachmark_initialmargin:初始基准利差(%)
                guaranteed_rate:债券保底利率(%)
                firstpricing_date:首个定价日
                Intrate_adjustmode:利率调整模式
                issue_date:发行日
                frstvalue_date:起息日(债券期限起始日)
                mrty_date :到期日(债券期限截止日)
                firstpay_date:首次理论付息日
                reg_date:债权债务登记日
                listing_date:上市日(交易流通起始日)
                delisted_date:摘牌日(交易流通终止日)
                amrty_dat:实际到期日
                adelisted_date:摘牌日(实际)
    :return: pd.DataFrame
    """
    conn = db_conn.get_basic_data_conn()
    where = []
    if isinstance(bond_code, str):
        where.append(f'bond_code=\'{bond_code}\'')
    elif isinstance(bond_code, list):
        where.append(get_lst_condition(bond_code, 'bond_code'))
    else:
        LOG.error('目前fund_code只支持str、list。请按要求输入')
        raise NotImplementedError
    df = my_mysql.read_v2(
        select=select, where=where, sfrom=BOND_INFO_TABLE, conn=conn)
    conn.close()

    if df.empty:
        LOG.error(f"没有找到{bond_code}的信息，请检查输入")
        return
    if select is None:
        drop_column_list = ['tid', 'titime', 'tutime', 'tutimestamp',
                            'tcreator', 'tmodifier', 'tauditor', 'taudittime', 'tdatastate',
                            'tdatachannel', 'torigdatabuid']
        df = df.drop(columns=drop_column_list)

    return df


def get_conv_bond_valuation(bond_code=None,  only_latest=True,
                            start_date=None, end_date=None, select=None):

    conn = db_conn.get_derivative_data_conn()
    where = []

    # bond_code 过滤条件
    if isinstance(bond_code, str):
        where.append(f'bond_code=\'{bond_code}\'')
    elif isinstance(bond_code, list):
        where.append(get_lst_condition(bond_code, 'bond_code'))
    elif bond_code is None:
        where.append('1=1')  # 取所有可转债信息
    else:
        LOG.error('bond_code只支持str、list或者None。请按要求输入')
        raise NotImplementedError

    # 将日期转换成带杠字符串
    if start_date is None:
        start_date = EARLIEST_START_DATE
    else:
        start_date = time_tool.format_date_str(start_date, '%Y-%m-%d')
    if end_date is None:
        end_date = time_tool.get_today(marker='with_n_dash')
    else:
        end_date = time_tool.format_date_str(end_date, '%Y-%m-%d')

    if only_latest:
        if select is None:
            cols = '*'
        elif isinstance(select, list):
            cols = ', '.join(select)
        else:
            LOG.error(f"select参数为空或为list，请按要求输入")
            return
        sql_str = (f"select {cols} from {CONV_BOND_VALUATION} as a, "
                   f"(select bond_code as code, max(trade_date) as enddate "
                   f"from {CONV_BOND_VALUATION} "
                   f"where trade_date <= '{end_date}' "
                   f"and {where} group by bond_code) as b "
                   f"where a.bond_code = b.code "
                   f"and a.trade_date = b.enddate ")
        df = my_mysql.read_v3(sql_str, conn)
    else:
        where.append(f"trade_date >= '{start_date}'")
        where.append(f"trade_date <= '{end_date}'")
        df = my_mysql.read_v2(select=select, where=where, sfrom=CONV_BOND_VALUATION, conn=conn)

    conn.close()

    if df.empty:
        LOG.error(f"没有找到{bond_code}的数据，请检查")
        return

    if select is None:
        drop_column_list = ['tid', 'titime', 'tutime', 'tutimestamp',
                            'tcreator', 'tmodifier', 'tauditor', 'taudittime', 'tdatastate',
                            'tdatachannel', 'torigdatabuid']
        if only_latest:
            drop_column_list.extend(['code', 'enddate'])
        df.drop(columns=drop_column_list, inplace=True)

    if 'trade_date' in df.columns:
        df = df.rename(columns={'trade_date': 'end_date'})
        df['end_date'] = df['end_date'].apply(time_tool.format_date_str)
        df.sort_values(by=['end_date', 'bond_code'], ascending=True, inplace=True)  # 按照日期进行排序

    return df


if __name__ == '__main__':
    test = get_bond_basic_info('150203')


